package com.example.sandbox.util;

import com.example.sandbox.dto.Enum.Currency;
import com.example.sandbox.helper.BizException;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.FieldPosition;

/**
 * @author dingzhiwei jmdhappy@126.com
 * @version V1.0
 * @Description: 金额工具类
 * @date 2017-07-05
 * @Copyright: www.xxpay.org
 */
public class AmountUtil {

    /**
     * 将字符串"元"转换成"分"
     *
     * @param str
     * @return
     */
    public static String convertDollar2Cent(String str, String currencyStr) {
        Currency currency = Currency.of(currencyStr);
        // DecimalFormat df = new DecimalFormat("0.00");
        DecimalFormat df = new DecimalFormat(currency.getDecimalFormat());
        StringBuffer sb = df.format(Double.parseDouble(str), new StringBuffer(), new FieldPosition(0));
        int idx = sb.toString().indexOf(".");
        sb.deleteCharAt(idx);
        for (; sb.length() != 1;) {
            if (sb.charAt(0) == '0') {
                sb.deleteCharAt(0);
            } else {
                break;
            }
        }
        return sb.toString();
    }

    /**
     * 将Long "分"转换成"元"（长格式），如：100分被转换为1.00元。
     *
     * @param s
     * @return
     */
    public static String convertCent2Dollar(Long s, String currencyStr) {
        if (s == null) {
            return "";
        }
        Currency currency = Currency.of(currencyStr);
        // return new BigDecimal(s).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
        return new BigDecimal(s).divide(new BigDecimal(currency.getDivide()))
            .setScale(currency.getScale(), BigDecimal.ROUND_HALF_UP).toString();
    }

    /**
     * 将Long "分"转换成"元"（长格式），如：100分被转换为1.00元。 scale 代表保留小数点后几位
     *
     * @param s
     * @return
     */
    public static String convertCent2DollarScale(Long s, String currencyStr, int scale) {
        if (s == null) {
            return "";
        }
        Currency currency = Currency.of(currencyStr);
        // return new BigDecimal(s).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
        return new BigDecimal(s).divide(new BigDecimal(currency.getDivide())).setScale(scale, BigDecimal.ROUND_HALF_UP)
            .toString();
    }

    /**
     * 将Long "分"转换成"元"（长格式），如：100分被转换为1.00元。 scale 代表保留小数点后几位
     *
     * @param s
     * @return BigDecimal
     */
    public static BigDecimal convertCent2DollarBigDecimal(Long s, String currencyStr, int scale) {
        if (s == null) {
            return null;
        }
        Currency currency = Currency.of(currencyStr);
        // return new BigDecimal(s).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
        return new BigDecimal(s).divide(new BigDecimal(currency.getDivide())).setScale(scale, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 将Long "分"转换成"元"（长格式），如：100分被转换为1元。 只保留整数 不四舍五入
     *
     * @param s
     * @return BigDecimal
     */
    public static BigDecimal convertCent2DollarBigDecimal(Long s, String currencyStr) {
        if (s == null) {
            return null;
        }
        Currency currency = Currency.of(currencyStr);
        return new BigDecimal(s).divide(new BigDecimal(currency.getDivide())).setScale(0, RoundingMode.FLOOR);
    }

    /**
     * 计算百分比类型的各种费用值 （订单金额 * 真实费率 结果四舍五入并保留0位小数 ）
     *
     * @param amount 订单金额 （保持与数据库的格式一致 ，单位：分）
     * @param rate 费率 （保持与数据库的格式一致 ，真实费率值，如费率为0.55%，则传入 0.0055）
     * 
     * 
     * @date 2021/8/20 14:53
     */
    public static Long calPercentageFee(Long amount, BigDecimal rate) {
        return calPercentageFee(amount, rate, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 计算百分比类型的各种费用值 （订单金额 * 真实费率 结果四舍五入并保留0位小数 ）
     *
     * @param amount 订单金额 （保持与数据库的格式一致 ，单位：分）
     * @param rate 费率 （保持与数据库的格式一致 ，真实费率值，如费率为0.55%，则传入 0.0055）
     * @param mode 模式 参考：BigDecimal.ROUND_HALF_UP(四舍五入) BigDecimal.ROUND_FLOOR（向下取整）
     * 
     * 
     * @date 2021/8/20 14:53
     */
    public static Long calPercentageFee(Long amount, BigDecimal rate, int mode) {
        // 费率乘以订单金额 结果四舍五入并保留0位小数
        return new BigDecimal(amount).multiply(rate).setScale(0, mode).longValue();
    }

    /**
     * 参数不能为空
     * @param objects
     */
    public static void checkForNegativeNumbers(Object... objects) {
        for (Object obj : objects) {
            if (obj == null) {
                continue; // 跳过 null 值
            }
            if (obj instanceof BigDecimal) {
                // 检查最小值和最大值
                if (((BigDecimal) obj).compareTo(BigDecimal.ZERO) < 0 || ((BigDecimal) obj).compareTo(new BigDecimal("1.00")) > 0) {
                    throw new BizException("参数必须在范围 0.00 到 1.00 之间: " + obj);
                }
                // 检查数字类型
                if (((BigDecimal) obj).doubleValue() < 0) {
                    throw new BizException("参数不能为负数: " + obj);
                }
            } else if (obj instanceof String) {
                // 检查字符串首字符
                String str = (String) obj;
                if (!str.isEmpty() && str.charAt(0) == '-') {
                    throw new BizException("参数不能为负数: " + str);
                }
            }
        }
    }


}
